package cc.rengu.igas.cops.core.service.trans.unionpay;

import cc.rengu.igas.channel.upqc.facade.bean.CouponInfoBean;
import cc.rengu.igas.channel.upqc.facade.bean.PayeeInfoBean;
import cc.rengu.igas.channel.upqc.facade.bean.PayerInfo;
import cc.rengu.igas.channel.upqc.facade.bean.RiskInfoBean;
import cc.rengu.igas.channel.upqc.facade.request.B2CQueryCouponRequest;
import cc.rengu.igas.channel.upqc.facade.response.B2CQueryCouponResponse;
import cc.rengu.igas.channel.upqc.facade.result.Result;
import cc.rengu.igas.cops.common.enums.RespCodeEnum;
import cc.rengu.igas.cops.facade.bean.CouponInfo;
import cc.rengu.igas.cops.facade.bean.RiskInfo;
import cc.rengu.igas.cops.facade.request.BankB2cQueryCouponRequest;
import cc.rengu.igas.cops.facade.response.BankB2cQueryCouponResponse;
import cc.rengu.igas.share.common.enums.UserPayAuthTypeEnum;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.oltp.service.base.BizBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.SignAcctInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.SignAcctInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.SignAcctInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.LimitTypeEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.model.RiskMonitorInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;

/**
 * 主扫---查询营销
 * 手机【ESB】—>支付—>通道—>银联
 * <p>
 * 订单表字段：
 * remark1：二维码类型(0：动态码 1：静态码)
 * remark2：收款方信息JSON
 * discount_info：优惠信息json list
 * front_seq_num前端流水号：付款凭证号
 *
 * @author panky
 * @version 1.0.0 创建时间：2020.06.23
 */
public class BankB2cQueryCouponService extends BizBaseService implements TransCustomImpl {

    @Override
    protected Object beforeBizProcess() throws Exception {
        BankB2cQueryCouponRequest bankB2cQueryCouponRequest = new BankB2cQueryCouponRequest();
        ConvertUtil.convertOutput(bankB2cQueryCouponRequest);
        return bankB2cQueryCouponRequest;
    }

    @Override
    protected BizResponse callBizService(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        // 录入参数
        BankB2cQueryCouponRequest bankB2cQueryCouponRequest = (BankB2cQueryCouponRequest) request;
        // 行号
        String instId = bankB2cQueryCouponRequest.getHeader().getInstId();
        // 用户编号
        String userId = bankB2cQueryCouponRequest.getUserId();
        SignAcctInfoMapper signAcctInfoMapper = new SignAcctInfoMapperImpl();
        List<SignAcctInfo> signList = signAcctInfoMapper.selectSignAcctInfoBySignToken(instId, bankB2cQueryCouponRequest.getSignToken());
        /// 没有查询到签约账号
        if (signList == null || signList.size() == 0
                || !userId.equals(signList.get(0).getUserId())
                || AppParamConstant.NO.equals(signList.get(0).getSignStatus())) { // 签约状态正常
            rglog.debug("查询用户签约账号异常");
            throw new BizException(OltpRpcdEnum.RECOND_EMPTY_OR_NOT_FOUND.getRespCode(), OltpRpcdEnum.RECOND_EMPTY_OR_NOT_FOUND.getRespDesc());
        }
        SignAcctInfo signAcctInfo = signList.get(0);

        // 获取用户订单信息表
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();

        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByOrderUrl(instId, bankB2cQueryCouponRequest.getTxnNo());
        if (null == userOrderInfo) {
            rglog.debug("查询用户订单异常");
            throw new BizException(OltpRpcdEnum.RECOND_EMPTY_OR_NOT_FOUND.getRespCode(), OltpRpcdEnum.RECOND_EMPTY_OR_NOT_FOUND.getRespDesc());
        }

        SysParamService sysParamService = new SysParamServiceImpl();
        /* 银联码，获取法人行在银联的机构号 */
        SysParam unionPayCode = sysParamService.getSysParamInfo(instId, "OPMS_SYS_PARAM", "unionPayerOrgCode" + "_" + bankB2cQueryCouponRequest.getQddm());
        if (null == unionPayCode) {
            rglog.error("获取二维码服务失败！获取法人行在银联的机构号失败！instId:{}", instId);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        // 银联机构号
        String strUnonPayCode = unionPayCode.getParamValue();

        B2CQueryCouponRequest b2CQueryCouponRequest = new B2CQueryCouponRequest();

        PayerInfo payerInfo = new PayerInfo();

        // 付款人员信息
        // 本他行判断
        if ("0".equals(signAcctInfo.getSignAcctType().substring(0, 1))) {
            payerInfo.setAccNo(signAcctInfo.getSignAcctNo());
        } else {
            // 他行使用TOKEN
            payerInfo.setAccNo(signAcctInfo.getSignToken());
        }
        // card_hold_name
        payerInfo.setName(signAcctInfo.getCardHoldName());
        // 签约银行名称
        //payerInfo.setPayerBankInfo(signAcctInfo.getSignBankName());
        // 贷记卡判断
        // 01-本行贷记账户
        // 11-他行贷记账户
        if ("01".equals(signAcctInfo.getSignAcctType()) || "11".equals(signAcctInfo.getSignAcctType())) {
            payerInfo.setCardAttr("02"); // 贷记卡
        } else {
            payerInfo.setCardAttr("01"); // 借记卡
        }
        // 预留手机号
        payerInfo.setMobile(signAcctInfo.getReserveMobileNo());
        b2CQueryCouponRequest.setPayerInfo(payerInfo);

        // 银联机构号
        b2CQueryCouponRequest.setIssInsCode(strUnonPayCode);
        // 订单金额	orderAmt --与页面交互，无需除以100
        b2CQueryCouponRequest.setOrderAmt(bankB2cQueryCouponRequest.getTxnAmt());
        //交易顺序号	txnNo
        b2CQueryCouponRequest.setTxnNo(bankB2cQueryCouponRequest.getTxnNo());

        // 收款方信息	payeeInfoBean
        PayeeInfoBean payeeInfoBean = JSON.parseObject(userOrderInfo.getRemark2(), PayeeInfoBean.class);
        b2CQueryCouponRequest.setPayeeInfoBean(payeeInfoBean);

        //风控信息	riskInfo
        RiskInfoBean riskInfo = new RiskInfoBean();
        RiskInfo webRiskInfo = bankB2cQueryCouponRequest.getRiskInfo();
        riskInfo.setDeviceID(webRiskInfo.getDevId());
        riskInfo.setDeviceName(webRiskInfo.getDeviceMode());
        riskInfo.setSourceIP(webRiskInfo.getTermIp());
        riskInfo.setDeviceLocation(webRiskInfo.getDeviceLocation());
        riskInfo.setDeviceType(webRiskInfo.getDeviceMode());
        //风控信息	riskInfo
        if (StringUtil.isEmptyOrNull(webRiskInfo.getDevId())) {
            riskInfo.setDeviceID("DevId");
        } else {
            riskInfo.setDeviceID(webRiskInfo.getDevId());
        }
        if (StringUtil.isEmptyOrNull(webRiskInfo.getDeviceMode())) {
            riskInfo.setDeviceName("DeviceMode");
        } else {
            riskInfo.setDeviceName(webRiskInfo.getDeviceMode());
        }
        if (StringUtil.isEmptyOrNull(webRiskInfo.getTermIp())) {
            riskInfo.setSourceIP("127.0.0.1");
        } else {
            riskInfo.setSourceIP(webRiskInfo.getTermIp());
        }
        riskInfo.setDeviceLocation(webRiskInfo.getDeviceLocation());
        if (StringUtil.isEmptyOrNull(webRiskInfo.getDeviceMode())) {
            riskInfo.setDeviceType("DeviceType");
        } else {
            riskInfo.setDeviceType(webRiskInfo.getDeviceMode());
        }
        //应用提供方账户ID
        if (!StringUtil.isEmptyOrNull(userOrderInfo.getUserId())) {
            riskInfo.setAccountIdHash(MD5Util.MD5Encode(userOrderInfo.getUserId()));
        }
        //银行预留手机号
        if (!StringUtil.isEmptyOrNull(signAcctInfo.getReserveMobileNo())) {
            riskInfo.setMobile(signAcctInfo.getReserveMobileNo());
        }
        //账户注册日期  8 位日期字符 yyyymmdd
        if (!StringUtil.isEmptyOrNull(userOrderInfo.getCreateTime())) {
            riskInfo.setUsrRgstrDt(DateUtil.dateStringFormatConvert(userOrderInfo.getCreateTime(), "yyyy-MM-dd HH:mm:ss.SSS", "yyyyMMdd"));
        }

        b2CQueryCouponRequest.setRiskInfo(riskInfo);

        cc.rengu.igas.channel.upqc.facade.base.Header upHeader = new cc.rengu.igas.channel.upqc.facade.base.Header();
        BeanUtil.beanCopy(bankB2cQueryCouponRequest.getHeader(), upHeader);
        upHeader.setTxnNum("0180000903");// 查询营销
        upHeader.setSrcSysId("OPMS");
        b2CQueryCouponRequest.setHeader(upHeader);
        b2CQueryCouponRequest.setOrderCcy("156");
        // 查询营销
        DubboService dubboService = new DubboServiceImpl();
        Result<B2CQueryCouponResponse> responseResult = (Result<B2CQueryCouponResponse>) dubboService.callDubboService("upqcPayerService", "b2cQueryCoupon", b2CQueryCouponRequest);
        if (null == responseResult || !responseResult.isSuccess() || !"00000000".equals(responseResult.getResult().getRespCode())) {
            // 没有营销继续向下走
//            rglog.error("调用银联查询二维码优惠信息失败，二维码订单号<{}>信息失败,iReturnCode:<{}>",
//                    bankB2cQueryCouponRequest.getTxnNo(),
//                    responseResult.getResult().getRespCode());
//            throw new BizException(RespCodeEnum.GET_QRCODE_INFO_ERROR.getRespCode(),RespCodeEnum.GET_QRCODE_INFO_ERROR.getRespDesc());
        }

        // 计算优惠金额
        String couponAmt = "0";
        List<CouponInfo> couponInfoList = new ArrayList<CouponInfo>();
        if (null != responseResult.getResult().getCouponInfoList()
                && responseResult.getResult().getCouponInfoList().size() != 0) {
            for (CouponInfoBean couponInfoBean : responseResult.getResult().getCouponInfoList()) {
                // 优惠累加
                couponAmt = AmountUtil.addition(couponAmt, couponInfoBean.getOffstAmt());

                // 复制Bean
                CouponInfo reCouBean = new CouponInfo();
                BeanUtil.beanCopy(couponInfoBean, reCouBean);
                couponInfoList.add(reCouBean);
            }
        }
        // 交易金额
        userOrderInfo.setOrderAmt(bankB2cQueryCouponRequest.getTxnAmt());
        // 实际支付金额
        userOrderInfo.setNeedPayAmt(AmountUtil.subtraction(userOrderInfo.getOrderAmt(), couponAmt));
        // 实际优惠总金额
        userOrderInfo.setRealDiscountAmt(couponAmt);
        if (responseResult.getResult().getCouponInfoList() != null) {
            // 优惠信息列表
            userOrderInfo.setDiscountInfo(JSON.toJSONString(responseResult.getResult().getCouponInfoList()));
        }

        OrderService orderService = new OrderServiceImpl();
        // 更新状态
        boolean isOrderCode = orderService.updateOrderInfo(userOrderInfo, null, null);
        if (!isOrderCode) {
            rglog.error("更新用户订单表失败!");
            throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.ORDER_NOEXIT.getRespDesc());
        }

        BankB2cQueryCouponResponse bankB2cQueryCouponResponse = new BankB2cQueryCouponResponse();
        // 优惠信息列表
        bankB2cQueryCouponResponse.setCouponInfo(couponInfoList);
        // 优惠金额
        bankB2cQueryCouponResponse.setCouptxnAmt(couponAmt);
        // 应付金额
        bankB2cQueryCouponResponse.setTxnAmt(AmountUtil.subtraction(userOrderInfo.getOrderAmt(), couponAmt));
        // 0：动态码
        // 1：静态码
        String bsnCode = LimitTypeEnum.B2C_STATIC.getLimitType();
        // 动态二维码
        if ("0".equals(userOrderInfo.getRemark1())) {
            bsnCode = LimitTypeEnum.C2B_QR.getLimitType();
        }
        // 验证方式
        // 01 密码验证
        // 02 密码+短信验证
        // 03 密码+软Ukey
        String limitInst = bankB2cQueryCouponRequest.getHeader().getInstId() + "|" + bankB2cQueryCouponRequest.getHeader().getInstId() + "|" + userOrderInfo.getUserId();
        UserService userService = new UserServiceImpl();
        UserPayAuthTypeEnum userPayAuthTypeEnum = userService.getUserPayAuthType(instId, bankB2cQueryCouponRequest.getUserId(), userOrderInfo.getOrderAmt(), LimitTypeEnum.CASHIER.getLimitType());
        String authType = userPayAuthTypeEnum.getType();
        bankB2cQueryCouponResponse.setCheckType(authType);

        // 返回
        BizResponse bizResponse = new BizResponse();
        bizResponse.setResult(bankB2cQueryCouponResponse);// 返回结果
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void afterBizProcess(BizResponse response) throws Exception {
        BankB2cQueryCouponResponse retResponse = (BankB2cQueryCouponResponse) response.getResult();
        ConvertUtil.convertInput(retResponse);
    }

    @Override
    protected RiskMonitorInfo getRiskMonitorInfo() {
        return null;
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        return null;
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return null;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}
